package gsd.gaudi.client;

import gsd.gaudi.client.anonymizer.GaudiATraceGenerator;
import gsd.gaudi.client.anonymizer.GaudiATraceGeneratorWithHeuristic;
import gsd.gaudi.client.anonymizer.GaudiEventReplayer;
import gsd.gaudi.client.converter.GaudiListeners2Events;
import gsd.gaudi.client.recorder.GaudiEventRecorder;
import gsd.gaudi.client.recorder.GaudiListenerRecorder;
import gsd.gaudi.client.recorder.exception.GuiUncaughtExceptionHandler;
import gsd.gaudi.client.ripper.GaudiRipper;
import gsd.gaudi.client.transformer.GuiTransformer;

/**
 * The main class of GaudiClient, use as a command line tool.
 * 
 * @author nunocoracao
 *
 */
public class GaudiClient {
	
	public static GaudiRipper gr;
	
	public static void main(String[] args) {
		
		
		
		if(args.length == 1 && args[0].equals("-h")){
			printHelp();
			System.exit(0);
		}
		
		else if(args.length >= 2 && args[0].equals("-launch")){
			
			System.out.println("[GaudiClient]-Normal Launching...");
			Launcher launcher = new Launcher(args[1], args);
			launcher.launch();

		}
		
		else if(args.length >= 2 && args[0].equals("-instrument")){
			
			System.out.println("[GaudiClient]-Launching instrumentation...");
			String[] argsaux = {args[1]};
			GuiTransformer.transform(argsaux);
			
		}
		
		else if(args.length >= 2 && args[0].equals("-launch")){
			
			System.out.println("[GaudiClient]-Normal Launching...");
			Launcher launcher = new Launcher(args[1], args);
			launcher.launch();
			
		}
		
		else if(args.length >= 2 && args[0].equals("-rip")){
			
			System.out.println("[GaudiClient]-Creating launcher...");
			Launcher launcher = new Launcher(args[1], args);
			
			System.out.println("[GaudiClient]-Creating ripper...");
			GaudiClient.gr = new GaudiRipper(args[1]);
			
			System.out.println("[GaudiClient]-Lauching application...");
			launcher.launch();
			
			System.out.println("[GaudiClient]-Ripping the gui...");
			gr.rip();
			
			Runtime.getRuntime().addShutdownHook(new Thread() {
			    @Override
			    public void run() {
			        gr.recordGuiStructure();
			        //gr.printStructure();
			    }
			});
		}
		
		else if(args.length >= 2 && args[0].equals("-recevents")){
			
			System.out.println("[GaudiClient]-Creating launcher...");
			Launcher launcher = new Launcher(args[1], args);
			
			System.out.println("[GaudiClient]-Creating recorder...");
			GaudiEventRecorder er = new GaudiEventRecorder(args[1]);
			
			System.out.println("[GaudiClient]-Starting uncaught exceptions catcher...");
			Thread.setDefaultUncaughtExceptionHandler(new GuiUncaughtExceptionHandler(er));
			
			System.out.println("[GaudiClient]-Lauching application...");
			launcher.launch();
			er.startRecording();
		}
		
		else if(args.length >= 2 && args[0].equals("-reclisteners")){
			
			System.out.println("[GaudiClient]-Creating launcher...");
			Launcher launcher = new Launcher(args[1], args);
			
			System.out.println("[GaudiClient]-Creating recorder...");
			GaudiListenerRecorder er = new GaudiListenerRecorder(args[1]);
		
			System.out.println("[GaudiClient]-Starting uncaught exceptions catcher...");
			Thread.setDefaultUncaughtExceptionHandler(new GuiUncaughtExceptionHandler(er));
			
			System.out.println("[GaudiClient]-Lauching application...");
			launcher.launch();
			er.startRecording();	
		}
		
		else if(args.length >= 3 && args[0].equals("-convertl2e")){
			
			System.out.println("[GaudiClient]-Creating converter...");
			GaudiListeners2Events converter = new GaudiListeners2Events(args[1], args[2]);
		
			System.out.println("[GaudiClient]-Converting tracefile...");
			converter.convert();
			converter.recordToFile();	
		}
		
		else if(args.length >= 4 && args[0].equals("-anonymize")){
			
			System.out.println("[GaudiClient]-Creating anonimizer...");
			GaudiATraceGenerator generator = new GaudiATraceGenerator(args[1], args[2], args[3]);
		
			System.out.println("[GaudiClient]-Generating reduced tracefiles...");
			generator.generate();	
			System.out.println("#################################");
			
			System.out.println("[GaudiClient]-Converting tracefiles");
			generator.convertAll();
			System.out.println("#################################");
			
			System.out.println("[GaudiClient]-verifying tracefiles");
			generator.testAll();
			
			System.out.println("#################################");
			
			System.out.println("[GaudiClient]-Trying to cut reduced tracefile...");
			generator.anonymizeReducedSequence();
			generator.convertAll();
			generator.testAll();
		}
		
		else if(args.length >= 4 && args[0].equals("-smartanonymize")){
			
			System.out.println("[GaudiClient]-Creating anonimizer...");
			GaudiATraceGeneratorWithHeuristic generator = new GaudiATraceGeneratorWithHeuristic(args[1], args[2], args[3]);
		
			System.out.println("[GaudiClient]-Generating reduced tracefiles...");
			generator.generate();
			generator.applyHeuristic();
			System.out.println("#################################");
			
			System.out.println("[GaudiClient]-Converting tracefiles");
			generator.convertAll();
			System.out.println("#################################");
			
			System.out.println("[GaudiClient]-verifying tracefiles");
			generator.testAll();
			
			System.out.println("#################################");
			
			System.out.println("[GaudiClient]-Trying to cut reduced tracefile...");
			generator.anonymizeReducedSequence();
			generator.applyHeuristic();
			generator.convertAll();
			generator.testAll();
		}
		
		else if(args.length >= 3 && args[0].equals("-testreplay")){
			
			System.out.println("[GaudiServer]-Creating launcher...");
			Launcher launcher = new Launcher(args[2], args);
			
			System.out.println("[GaudiServer]-Lauching application...");
			launcher.launch();
			
			System.out.println("[GaudiServer]-Lauching the event robot...");
			GaudiEventReplayer er = new GaudiEventReplayer(args[1]);
			er.replayEventSequence();
			
			Runtime.getRuntime().addShutdownHook(new Thread() {
			    @Override
			    public void run() {
			    	System.err.println("###FINITO####");
			    }
			});
			
		}
		
		else {
			System.out.println("[GaudiClient]-Invalid usage.");
			printHelp();
			System.exit(0);
		}
		
	}
	
	public static void printHelp(){
		System.out.println("### GaudiClient usage:");
		System.out.println("Usage Help\t\t: java -jar GaudiClient.jar -h");
		System.out.println("Launch app\t\t: java -jar GaudiClient.jar -launch MainClass");
		System.out.println("Instrument\t\t: java -jar GaudiClient.jar -instrument MainClass");
		System.out.println("Rip Graphical Interface\t: java -jar GaudiClient.jar -rip MainClass");
		System.out.println("Record Events\t\t: java -jar GaudiClient.jar -recevents MainClass");
		System.out.println("Record Listeners\t: java -jar GaudiClient.jar -reclisteners MainClass");
		//System.out.println("Record All\t\t: java -jar GaudiClient.jar -rec MainClass");
		System.out.println("Convert Tracefile\t: java -jar GaudiClient.jar -convertl2e guistructure tracefile");
		System.out.println("Generate anonymized\t: java -jar GaudiClient.jar -anonymize guistructure tracefile MainClass");
		System.out.println("Generate anonymized\t: java -jar GaudiClient.jar -smartanonymize guistructure tracefile MainClass");
	}
	
}
